<template>
	<div class="user-management">
		<div class="crumbs-wrapper">
			<Crumbs title="系统管理" sub-title="组织用户管理" />
		</div>
		<div class="main">
			<aside>
				<p class="header">组织机构</p>
				<p> <el-input size="small" placeholder="请输入查询内容" suffix-icon="el-icon-search" v-model="orgKeyword" /> </p>
				<div class="custom-tree-container">
					<div class="block">
						<el-tree ref="refOrgTree" :props="defaultProps" :data="orgTreeData" node-key="deptId"
							default-expand-all highlight-current
							:expand-on-click-node="false" :render-content="renderContent" :filter-node-method="filterNode"
							@node-click="clickNode">
						</el-tree>
					</div>
				</div>
				<section class="footer">
					<div @click="openImportOrg">
						<div class="iconfont icon-daochu"></div>
						<div>导入</div>
					</div>
					<div @click="exportOrg">
						<div class="iconfont icon-daoru1"></div>
						<div>导出</div>
					</div>
				</section>
			</aside>
			<article>
				<el-row>
					<el-form :inline="true" :model="searchFormData" size="small">
						<el-form-item label="账号名称">
							<el-input v-model="searchFormData.userName" placeholder="请输入" clearable></el-input>
						</el-form-item>
						<el-form-item label="集团名称">
							<el-input v-model="searchFormData.groupName" placeholder="请输入" clearable></el-input>
						</el-form-item>
						<el-form-item> <el-button type="default" @click="reset">重置</el-button> </el-form-item>
						<el-form-item> <el-button type="primary" @click="search">查询</el-button> </el-form-item>
						<el-form-item> 
							<el-button type="primary" @click="showCreateDialog">新增</el-button> 
						</el-form-item>
						<el-form-item> <el-button type="primary" @click="download">模板下载</el-button> </el-form-item>
						<el-form-item> <el-button type="primary" @click="openImportUser">导入</el-button> </el-form-item>
						<el-form-item> <el-button type="primary" @click="exportUser">导出</el-button> </el-form-item>
						<el-form-item>
							<el-button type="primary" @click="removeUser">批量删除</el-button>
						</el-form-item>
					</el-form>
				</el-row>
				
				<el-row>
					<el-table ref="multipleTable" v-loading="tableLoading" :data="tableData" size="small"
						@select-all="selectAll" @select="rowSelect">
						<el-table-column type="selection" align="center"/>
						<el-table-column label="账号名称" prop="userName" align="center" width="120"/>
						<el-table-column label="集团名称" prop="groupName" align="center" width="140"/>
						<el-table-column label="公司名称" prop="compName" align="center" width="140"/>
						<el-table-column label="企业统一社会信用编码" prop="enterprise" align="center" width="160"/>
						<el-table-column label="姓名" prop="realName" align="center" width="90"/>
						<el-table-column label="邮箱" prop="email" align="center" width="150"/>
						<el-table-column label="手机" prop="phonenumber" align="center" width="110"/>
						<el-table-column label="注册日期" prop="createTime" align="center" width="160"/>
						<el-table-column fixed="right" label="操作" align="center" width="180">
							<template slot-scope="scope">
								<el-button @click="showSetRoleDialog(scope.row)" type="text" >添加角色</el-button>
								<el-button @click="showUpdateDialog(scope.row)" type="text" >编辑</el-button>
								<el-button @click="removeUser(scope.row)" type="text">删除</el-button>
							</template>
						</el-table-column>
					</el-table>
				</el-row>
				<!-- 分页 -->
				<p>
					<el-pagination background layout="total, sizes, prev, pager, next, jumper"
						:current-page="searchFormData.pageNum"
						:page-sizes="[10, 20, 30, 50]"
						:page-size="10"
						:total="searchFormData.total" 
						@size-change="pageSizeChange"
						@current-change="currentPageChange"
					  />
				</p>
			</article>
		</div>
		
		<!-- 新增/编辑dialog -->
		<el-dialog :title="userDialogType=='edit' ? '编辑用户' : '新增用户'" :visible.sync="userDialogVisible" @close="closeUserDialog" width="35%">
			<div>
				<el-form label-width="100px" size="small">
					<el-form-item label="账号名称" required>
						<el-input v-model="userFormData.userName" :disabled="userDialogType=='edit'" placeholder="请输入账号名称"></el-input>
					</el-form-item>
					<el-form-item label="账号密码" required>
						<el-input type="password" v-if="userDialogType=='new'" v-model="userFormData.password" placeholder="请输入账号密码"></el-input>
						<el-input type="password" v-if="userDialogType=='edit'" v-model="userFormData.password" placeholder="请输入新的账号密码, 不输入则表示不更改"></el-input>
					</el-form-item>
					<el-form-item label="姓名">
						<el-input v-model="userFormData.realName" placeholder="请输入姓名"></el-input>
					</el-form-item>
					<el-form-item label="邮箱">
						<el-input v-model="userFormData.email" placeholder="请输入邮箱"></el-input>
					</el-form-item>
					<el-form-item label="手机号">
						<el-input v-model="userFormData.phonenumber" placeholder="请输入手机号"></el-input>
					</el-form-item>
				</el-form>
			</div>
			<span slot="footer" class="dialog-footer">
				<el-button @click="userDialogVisible = false">取 消</el-button>
				<el-button v-if="userDialogType=='edit'" type="primary" @click="saveEditUser">确 定</el-button>
				<el-button v-if="userDialogType=='new'" type="primary" @click="saveCreateUser">确 定</el-button>
			</span>
		</el-dialog>
		
		<!-- 添加角色弹窗 -->
		<el-dialog title="添加角色" :visible.sync="setRoleDialogVisible" width="40%" :append-to-body="true">
			<el-transfer v-model="setRoleFormData.rightList" 
				:data="setRoleFormData.lefList" :titles="['未添加角色', '已添加角色']"
				:props="{ key: 'roleId', label: 'roleName'}"/>
			<span slot="footer" class="dialog-footer">
				<el-button @click="setRoleDialogVisible = false">取 消</el-button>
				<el-button type="primary" @click="saveUserRole">确 定</el-button>
			</span>
		</el-dialog>
		
		<!-- 目录树节点新增/编辑 dialog -->
		<el-dialog :title="nodeDialogType=='new'?'新增节点':'编辑节点'" :visible.sync="nodeDialogVisible" width="35%">
			<div>
				<el-form :model="treeNode" label-width="100px">
					<el-form-item label="节点名称" required>
						<el-input v-model="treeNode.deptName" placeholder="请输入节点名称"></el-input>
					</el-form-item>
					<el-form-item label="节点类别" required>
						<el-select v-model="treeNode.deptType" placeholder="节点类别" style="width: 100%;">
							<el-option label="集团" :value="1"></el-option>
							<el-option label="公司" :value="2"></el-option>
						</el-select>
					</el-form-item>
					<el-form-item label="节点排序">
						<el-input v-model="treeNode.orderNum" placeholder="请输入节点排序"></el-input>
					</el-form-item>
				</el-form>
			</div>
			<span slot="footer" class="dialog-footer">
				<el-button @click="nodeDialogVisible = false">取 消</el-button>
				<el-button v-if="nodeDialogType=='new'" type="primary" @click="saveAppendNode">确 定</el-button>
				<el-button v-if="nodeDialogType=='edit'" type="primary" @click="saveEditNode">确 定</el-button>
			</span>
		</el-dialog>
		
		<!-- 组织机构用户导入窗口 -->
		<el-dialog title="导入资源" :visible.sync="importUserDialogVisible" width="35%">
			<div>
				<el-upload action="/api/system/user/importData" ref="refImportUser"
					:auto-upload="false"
					:on-success="uploadUserSuccess"
					:on-error="(e) => { this.$message.error(e) }"
					:file-list="userFiles" :limit="1" name="file">
					<el-button size="small" type="success">选取文件</el-button>
					<div slot="tip" class="el-upload__tip">只能上传导出的文件，且字段不可更改</div>
				</el-upload>
			</div>
			<span slot="footer">
				<el-button size="small" @click="importUserDialogVisible = false">取 消</el-button>
				<el-button size="small" type="primary" @click="importUser">保 存</el-button>
			</span>
		</el-dialog>
		
		<!-- 公司组织结构导入窗口 -->
		<el-dialog title="导入资源" :visible.sync="importOrgDialogVisible" width="35%">
			<div>
				<el-upload action="/api/system/dept/importData" ref="refImportOrg"
					:auto-upload="false"
					:on-success="uploadOrgSuccess"
					:on-error="(e) => { this.$message.error('导入组织机构失败，请检查文件格式后重试') }"
					:file-list="orgFiles" :limit="1" name="file">
					<el-button size="small" type="success">选取文件</el-button>
					<div slot="tip" class="el-upload__tip">只能上传导出的文件，且字段不可更改</div>
				</el-upload>
			</div>
			<span slot="footer">
				<el-button size="small" @click="importOrgDialogVisible = false">取 消</el-button>
				<el-button size="small" type="primary" @click="importOrg">保 存</el-button>
			</span>
		</el-dialog>
	</div>
</template>

<script>
	export default {
		components: {},
		data() {
			return {
				importOrgDialogVisible: false, //导入组织机构的弹窗是否可见
				importUserDialogVisible: false, //导入用户弹窗是否可见
				setRoleDialogVisible: false, //添加角色弹窗是否可见
				nodeDialogVisible: false, //是否显示树节点新增/编辑弹窗
				nodeDialogType: 'new', //树节点弹窗类型 ： 新增 / 编辑
				userDialogVisible: false, //用户添加编辑弹窗是否可见
				userDialogType: 'new', //用户弹窗类型 ： 新增 / 编辑
				treeNode: { //要新增/编辑的树节点
					deptName: '',
					deptType: '',
					orderNum: ''
				},
				orgKeyword: '', //组织机构查询关键字
				orgTreeData: [], 
				defaultProps: { //树形结构节点属性别名
					'label': 'deptName'
				},
				searchFormData: { //搜索表单
					userName: '',
					groupName: '',
					deptId: -1, //所属机构ID， 默认根节点
					pageNum: 1,
					pageSize: 10,
					total: 0
				},
				userFormData: {
					userName: '',
					password: '',
					realName: '',
					email: '',
					phonenumber: ''
				},
				initUserFormData: {
					userName: '',
					password: '',
					realName: '',
					email: '',
					phonenumber: ''
				},
				setRoleFormData: { //添加角色时的Data数据
					lefList: [], //全部角色列表
					rightList: [] //已拥有的角色列表
				},
				tableData: [], //用户列表
				tableLoading: false,
				selectedUserList: [] ,//选中的行
				userFiles: [] ,//导入用户文件
				orgFiles: [] //导入组织机构文件
			}
		},
		created() {
			this.loadTreeData()
		},
		mounted() {
			
		},
		methods: {
			importOrg() {
				this.$refs.refImportOrg.submit();
			},
			exportOrg() {
				this.$util.download('/api/system/dept/export')
			},
			openImportOrg() {
				this.importOrgDialogVisible = true;
			},
			uploadOrgSuccess() {
				this.$message.success('组织机构导入成功')
				this.importOrgDialogVisible = false;
				this.loadTreeData()
			},
			importUser() { //提交导入文件
				this.$refs.refImportUser.submit();
			},
			exportUser() {
				this.$util.download('/api/system/user/export?deptId='+this.searchFormData.deptId)
			},
			openImportUser() { //打开导入用户弹窗
				this.importUserDialogVisible = true;
			},
			uploadUserSuccess() { //上传成功回调方法
				this.$message.success('用户导入成功')
				this.userFiles = [];
				this.importUserDialogVisible = false;
				this.loadTableData()
			},
			appendNode(node, data) { //节点新增前准备工作，同时弹出节点新增窗口
				this.selectedTreeNode = data; //记录当前选中的节点
				this.treeNode = {}
				this.nodeDialogVisible = true;
				this.nodeDialogType = 'new'
			},
			saveAppendNode() { //保存新增树节点
				//提交服务器保存
				this.$http({
					url: '/api/system/dept/add',
					method: 'POST',
					data: {
						...this.treeNode,
						"parentId": this.selectedTreeNode.deptId
					}
				}).then( res => {
					// console.log(res.data);
					this.loadTreeData(true)
					this.nodeDialogVisible = false;
				})
			},
			editNode(node,data) { //树节点编辑前准备工作,同时弹出节点编辑窗口
				this.selectedTreeNode = data; //记录当前选中的节点
				this.treeNode = {...data};
				this.nodeDialogVisible = true;
				this.nodeDialogType = 'edit'
			},
			saveEditNode() { //保存编辑树节点
				// console.log(this.treeNode);
				this.$http({
					url: '/api/system/dept/edit',
					method: 'POST',
					data: this.treeNode
				}).then( res => {
					this.loadTreeData(true);
					this.nodeDialogVisible = false;
				})
			},
			clickNode(data) { //点击树节点
				this.searchFormData.deptId = data.deptId;
				this.searchFormData.deptType = data.deptType;
				this.loadTableData();
			},
			filterNode(value, data) { //过滤树节点
				// console.log(value, data);
				if (!value) return true;
				return data.deptName.indexOf(value) !== -1;
			},
			removeNode(node, data) { //删除树节点
				this.$confirm('此操作将删除该节点, 是否继续?', '提示', {
					type: 'error'
				}).then(() => {
					this.$http({
						url: `/api/system/dept/${data.deptId}`,
						method: 'GET',
					}).then( res => {
						if(res.data.code == 200) {
							const parent = node.parent;
							const children = parent.data.children || parent.data;
							const index = children.findIndex(d => d.deptId === data.deptId);
							children.splice(index, 1);
						} else {
							this.$message.error(res.data.msg);
						}
					})
				})
			},
			renderContent(h, { node, data, store }) {  //树的render函数
				if(data.root) { //如果是根节点，则不允许编辑删除
					return (
					<span class="custom-tree-node">
						<el-tooltip content={data.deptName} effect="light" placement="top" open-delay="600" hide-after="2000">
							<span class="node-name">{data.deptName}</span>
						</el-tooltip>
						<span>
							<el-button size="medium" type="text" icon="el-icon-plus" on-click={ () => this.appendNode(node,data) }></el-button>
						</span>
					</span>);
				} else {
					return (
					<span class="custom-tree-node">
						<el-tooltip content={data.deptName} effect="light" placement="top" open-delay="600" hide-after="2000">
							<span class="node-name">{data.deptName}</span>
						</el-tooltip>
						<span>
							<el-button size="medium" type="text" icon="el-icon-plus" 
								on-click={ () => this.appendNode(node,data) }></el-button>
							<el-button size="medium" type="text" icon="el-icon-edit-outline" 
								on-click={ () => this.editNode(node,data) }></el-button>
							<el-button size="medium" type="text" icon="el-icon-delete" 
								on-click={ () => this.removeNode(node, data) }></el-button>
						</span>
					</span>);
				}
			},
			loadTreeData(keep) { //加载组织机构树形目录
				this.$http({
					url: '/api/system/dept/treeselect',
				}).then( res => {
					this.orgTreeData = res.data.data
					//给根节点手动加标记
					this.orgTreeData[0].root = true;
					
					this.$nextTick(()=>{
						if(!keep) { //keep代表了是否要保持之前选中状态不变，如果否，则选中默认根节点
							this.$refs.refOrgTree.setCurrentKey(this.orgTreeData[0].deptId); //选中根节点
						}
						this.searchFormData.deptId = this.orgTreeData[0].deptId;
						this.loadTableData()
					})
				})
			},
			showCreateDialog() { //打开创建用户窗口，
				this.userFormData = { //初始化formData
					userName: '',
					password: '',
					realName: '',
					email: '',
					phonenumber: ''
				}
				this.userDialogType = 'new';
				this.userDialogVisible = true;
			},
			showUpdateDialog(row) { //用户编辑前准备工作，同时弹出用户编辑窗口
				this.userFormData = row;
				this.userFormData.password = ''
				this.userDialogType = 'edit';
				this.userDialogVisible = true;
				for (const key in this.userFormData) {
					this.initUserFormData[key] = this.userFormData[key]
				}
			},
			saveEditUser() { //保存用户编辑
				this.$http({
					url: '/api/system/user/edit',
					method: 'POST',
					data: this.userFormData
				}).then(res => {
					console.log(res);
					if(res.data.code == 200) {
						this.userDialogVisible = false;
						this.loadTableData();
					} else {
						this.$message.error(res.data.msg);
					}
				})
			},
			saveCreateUser() { //保存新增用户
				this.$http({
					url: '/api/system/user/add',
					method: 'POST',
					data: {
						...this.userFormData,
						deptId: this.searchFormData.deptId
					}
				}).then(res => {
					console.log(res);
					if(res.data.code == 200) {
						this.userDialogVisible = false;
						this.loadTableData();
					} else {
						this.$message.error(res.data.msg);
					}
				})
			},
			// 关闭编辑用户窗口
			closeUserDialog(){
				// console.log('this.userFormData',this.userFormData.realName,'-',this.initUserFormData.realName);
				for (const key in this.initUserFormData) {
					if (this.userFormData.hasOwnProperty(key)) {
						this.userFormData[key] = this.initUserFormData[key]
					}
				}
			},
			removeUser(row) {
				this.$confirm('此操作将删除该用户, 是否继续?', '提示', {
					type: 'error'
				}).then(() => {
					let userIds = row.userId ? row.userId : this.selectedUserList.map(r=>r.userId).join(",")
					this.$http({
						url: `/api/system/user/remove/${userIds}`,
					}).then( res => {
						this.$message.success('删除成功');
						this.loadTableData()
					})
				})
			},
			selectAll(list) { //选择所有行
				this.selectedUserList = list;
			},
			rowSelect(list) { //选择某一行
				this.selectedUserList = list;
			},
			currentPageChange(pageNum) { //当前页发生变化
				this.searchFormData.pageNum = pageNum
				this.loadTableData()
			},
			loadTableData() { //加载表格数据
				this.tableLoading = true;
				this.$http({
					url: '/api/system/user/list',
					method: 'POST',
					data: this.searchFormData
				}).then( res => {
					this.tableLoading = false;
					this.tableData = res.data.rows;
					this.searchFormData.total = res.data.total;
					// console.log(res.data.rows);
				})
			},
			pageSizeChange(pageSize) {
				this.searchFormData.pageSize = pageSize;
				this.searchFormData.pageNum = 1;
				this.loadTableData()
			},
			reset() {
				this.searchFormData.userName = '';
				this.searchFormData.groupName = '';
				this.searchFormData.pageNum = 1;
				this.loadTableData()
			},
			search() {
				this.loadTableData();
			},
			showSetRoleDialog(row) {
				//查询该用户的角色列表, 以及全部角色列表
				this.setRoleFormData.userId = row.userId;
				this.$http({
					url: `/api/system/user/authRole/${row.userId}`,
					method: 'GET'
				}) .then( res => {
					let roleList = res.data.data;
					
					let _rightList = []
					//过滤列表，筛选出已分配和未分配，同时，将租户管理员，设置为disabled
					roleList.forEach(role=>{
						if(role.roleCode == 'TENANT_ADMIN') role.disabled = true
						if(role.flag) _rightList.push(role.roleId)
					})
					this.setRoleFormData.lefList = roleList;  //左侧角色列表
					this.setRoleFormData.rightList = _rightList; //右侧角色列表
					
					this.setRoleDialogVisible = true
				})
				
			},
			download() {
				this.$util.download('/api/system/user/importTemplate');
			},
			saveUserRole() { //保存添加的角色
				this.$http({
					url: '/api/system/user/saveAuthRole',
					method: 'POST',
					data: {
						'roleIds': this.setRoleFormData.rightList,
						'userId': this.setRoleFormData.userId 
					}
				}).then( res => {
					console.log(res);
					this.setRoleDialogVisible = false
				})
			}
		},
		computed: {
			loginUser() {
				return this.$store.state.loginUser;
			}
		},
		watch: {
			orgKeyword(val) {
				// console.log(val);
				this.$refs.refOrgTree.filter(val);
			}
		}
	}
</script>

<style lang="scss" scoped>
	.user-management {
		height: calc(100vh - 100px);
		background-color: #f8f8f8;
		padding: 5px 30px 10px;

		.crumbs-wrapper {}

		.main {
			height: 92%;
			overflow-y: auto;
			box-sizing: border-box;
			padding: 0 10px 10px;
			display: flex;
			justify-content: space-between;
			> aside {
				.custom-tree-container {
					height: calc(100% - 160px);
					overflow-y: auto;
				}
				height: 100%;
				width: 20%;
				background-color: white;
				box-sizing: border-box;
				padding: 0 10px;
				position: relative;
				.header {
					text-align: center;
					font-size: 20px;
				}
				.footer {
					font-size: 14px;
					display: flex;
					height: 50px;
					justify-content: center;
					align-items: center;
					.iconfont {
						font-size: 18px;
					}
					div {
						margin: 0 10px;
						text-align: center;
						cursor: pointer;
					}
				}
			}
			> article {
				height: 100%;
				overflow-y: auto;
				width: 79%;
				background-color: white;
				box-sizing: border-box;
				padding: 20px;
			}
		}
	}
</style>
<style>
	.custom-tree-node {
	    flex: 1;
	    display: flex;
	    align-items: center;
	    justify-content: space-between;
	    font-size: 14px;
	    padding-right: 8px;
		.node-name {
			white-space: nowrap;
			overflow: hidden;
			text-overflow: ellipsis;
		}
	}
</style>
